package org.aerie.forest.core.frame.rebar.entity.processer.exception;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.aerie.forest.core.brick.exception.ExceptionGradeEnum;
import org.aerie.forest.core.brick.exception.ExceptionPack;
import org.aerie.forest.core.brick.exception.custom.ForestException;
import org.aerie.forest.core.brick.exception.custom.runtime.ForestBanNew;
import org.aerie.forest.core.brick.exception.custom.runtime.ForestRuntimeException;
import org.aerie.forest.core.frame.rebar.entity.processer.AbstractForestProcessor;
import org.aerie.forest.core.frame.rebar.entity.processer.ProcessPack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @description 异常处理器
 *
 * @author quark
 * @organization aerie
 * @date 2020年2月23日 上午10:39:47
 * @version 1.2.0
 */
public final class ExceptionProcessor extends AbstractForestProcessor<ProcessPack, Void> {

	/**
	 * @description forest静态内部类单例
	 *
	 * @author quark
	 * @organization aerie
	 * @date 2020-7-9 20:30:37
	 * @version 2.0.1
	 */
	private static final class ForestInstance {

		/**
		 * @description 单例对象
		 * 
		 * @author quark
		 * @date 2020-7-9 21:16:25
		 * @version 2.0.1
		 */
		private static final ExceptionProcessor EXCEPTION_PROCESSOR = new ExceptionProcessor();
	}

	/**
	 * @description 异常打印选择器
	 *
	 * @author quark
	 * @organization aerie
	 * @date 2020年2月24日 下午1:38:23
	 * @version 1.2.0
	 */
	private enum ExceptionStamper {

		/**
		 * @description 单例
		 * 
		 * @author quark
		 * @date 2020年2月24日 下午1:49:14
		 * @version 1.2.0
		 */
		INSTANCE;

		/**
		 * @description
		 * 
		 * @author quark
		 * @date 2020-7-23 16:08:41
		 * @version 2.0.1
		 */
		private static final Logger EXCEPTION_LOGGER = LoggerFactory.getLogger("ForestAsyncExceptionLogger");

		/**
		 * @description 选择相应的异常打印器并打印异常
		 * @param exceptionLogger        异常处理的记录器
		 * @param message                异常等级
		 * @param enumExceptionGradeEnum
		 *
		 * @date 2020年2月25日 下午5:44:57
		 * @version 1.2.0
		 */
		private void printException(String message, ExceptionGradeEnum enumExceptionGradeEnum) {
			printException(message, null, enumExceptionGradeEnum);
		}

		/**
		 * 
		 * @description 选择相应的异常打印器并打印异常
		 * @param exceptionLogger        异常处理的记录器
		 * @param message                异常信息
		 * @param throwable              需要打印的异常
		 * @param enumExceptionGradeEnum 异常等级
		 * 
		 * @date 2019年10月20日 下午11:17:30
		 * @version 1.2.0
		 */
		private void printException(String message, Throwable throwable, ExceptionGradeEnum enumExceptionGradeEnum) {
			switch (Optional.ofNullable(enumExceptionGradeEnum).orElse(ExceptionGradeEnum.WARN)) {
			case WARN:
				EXCEPTION_LOGGER.warn(message, throwable);
				break;
			case ERROR:
				EXCEPTION_LOGGER.error(message, throwable);
				break;
			case FATAL:
				// FATAL标记
				EXCEPTION_LOGGER.error(MARKER_FATAL, message, throwable);
				break;
			}
		}

		/**
		 * @description 选择相应的异常打印器并打印异常
		 * @param exceptionLogger
		 * @param enumExceptionGradeEnum
		 * @param format
		 * @param arguments
		 *
		 * @author quark
		 * @date 2020年5月4日 上午10:11:55
		 * @version 1.2.0
		 */
		void printException(ExceptionGradeEnum enumExceptionGradeEnum, String format, Object... arguments) {
			switch (Optional.ofNullable(enumExceptionGradeEnum).orElse(ExceptionGradeEnum.WARN)) {
			case WARN:
				EXCEPTION_LOGGER.warn(format, arguments);
				break;
			case ERROR:
				EXCEPTION_LOGGER.error(format, arguments);
				break;
			case FATAL:
				EXCEPTION_LOGGER.error(format, arguments);
				break;
			}
		}

	}

	/**
	 * Construction
	 * 
	 * @author quark
	 * @date 2020年2月23日 上午10:42:32
	 * @version 1.2.0
	 */
	private ExceptionProcessor() {
		super("异常处理器");
		LOGGER.debug(LogMsgPool.INIT_COMPLETE, forestFrameName);
	}

	/**
	 * @description 获得全局异常包装处理器单例
	 * @return 异常处理器单例
	 *
	 * @author quark
	 * @date 2020年2月23日 上午10:44:06
	 * @version 1.2.0
	 */
	public static ExceptionProcessor getInstance() {
		// 返回异常处理器静态内部类单例
		return ForestInstance.EXCEPTION_PROCESSOR;
	}

	/**
	 * @description 默认异常等级
	 * 
	 * @author quark
	 * @date 2020年2月23日 上午10:41:31
	 * @version 1.2.0
	 */
	private ExceptionGradeEnum defaultExceptionGrade = ExceptionGradeEnum.WARN;

	/**
	 * @description 自定义final字符串
	 *
	 * @author quark
	 * @organization aerie
	 * @date 2020年5月4日 下午4:30:12
	 * @version 1.2.0
	 */
	private static final class CustomString {

		/**
		 * Construction
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午5:58:07
		 * @version 1.2.0
		 */
		private CustomString() {
			// 禁止实例化
			throw new ForestBanNew(CustomString.class);
		}

		/**
		 * @description 回车换行
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午4:38:04
		 * @version 1.2.0
		 */
		private static final String NEW_LINE = "\r\n";

		/**
		 * @description 边框线
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午2:59:27
		 * @version 1.2.0
		 */
		private static final String BORDER_LINE = "*************************************************************************************************************************************************************************************************************";

		/**
		 * @description 自定义的一个字符串
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午3:00:45
		 * @version 1.2.0d
		 */
		private static final String BORDER_TAIL = "######";

		/**
		 * @description 堆栈信息前缀1
		 * 
		 * @author quark
		 * @date 2020-8-4 14:42:50
		 * @version 2.0.1
		 */
		private static final String STACK_TRACE_HEAD$1 = "`       => ";

		/**
		 * @description 堆栈信息前缀2
		 * 
		 * @author quark
		 * @date 2020-8-7 15:14:03
		 * @version 2.0.1
		 */
		private static final String STACK_TRACE_HEAD$2 = "        at ";

		/**
		 * @description 分隔符1
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午5:15:49
		 * @version 1.2.0
		 */
		private static final String DIVISION$1 = "be caused by:                                                                                                                                                                                                ######";

		/**
		 * @description 分隔符2
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午3:13:58
		 * @version 1.2.0
		 */
		private static final String DIVISION$2 = "        --------------------------------------------------------------------------------------------------------------->[";

		/**
		 * @description 分隔符3
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午5:06:08
		 * @version 1.2.0
		 */
		private static final String DIVISION$3 = "]                                                                     ######";

		/**
		 * @description 指定空格
		 * 
		 * @author quark
		 * @date 2020年5月4日 下午3:02:21
		 * @version 1.2.0
		 */
		private static final String BLANK = "                                                                                                                                                                                                             ";

		/**
		 * @description log头1
		 * 
		 * @author forest
		 * @date 2020-7-28 17:16:24
		 * @version 2.0.1
		 */
		private static final String LOG_HEAD$1 = "[";

		/**
		 * @description log头2
		 * 
		 * @author quark
		 * @date 2020-8-7 15:49:12
		 * @version 2.0.1
		 */
		private static final String LOG_HEAD$2 = "]   <";

		/**
		 * @description log头3
		 * 
		 * @author quark
		 * @date 2020-8-7 15:49:21
		 * @version 2.0.1
		 */
		private static final String LOG_HEAD$3 = ">`    | ";

		/**
		 * @description log头4
		 * 
		 * @author quark
		 * @date 2020-8-7 15:49:33
		 * @version 2.0.1
		 */
		private static final String LOG_HEAD$4 = " |                                                                                    []——>      ";
		/**
		 * @description log头5
		 * 
		 * @author quark
		 * @date 2020-8-4 13:51:17
		 * @version 2.0.1
		 */
		private static final String LOG_HEAD$5 = "<——————>{}";

		/**
		 * @description 打印信息的时间的格式
		 * 
		 * @author quark
		 * @date 2020-8-8 15:19:28
		 * @version 2.0.1
		 */
		private static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss,SSS";

		/**
		 * @description 错误退出
		 * 
		 * @author quark
		 * @date 2020-8-8 0:18:10
		 * @version 2.0.1
		 */
		private static final String ERROR_FINISH = "检测到error，结束当前线程";
	}

	/**
	 * @description 处理异常
	 * @param message   异常信息
	 * @param exception 处理的异常
	 *
	 * @date 2020年2月23日 上午10:47:35
	 * @version 1.2.0
	 */
	public void recordException(String message, Exception exception) {
		ExceptionGradeEnum finalExceptionGrade = finalExceptionGrade(exception, null);
		// 解析异常
		// 执行异常处理动作
		disposeFunction(null, finalExceptionGrade, analysisException(message, exception, finalExceptionGrade));
	}

	/**
	 * @description 处理异常
	 * @param message            异常信息
	 * @param exception          处理的异常
	 * @param exceptionGradeEnum 异常的等级
	 *
	 * @date 2020年2月23日 上午10:47:55
	 * @version 1.2.0
	 */
	public void recordException(String message, Exception exception, ExceptionGradeEnum exceptionGradeEnum) {
		ExceptionGradeEnum finalExceptionGrade = finalExceptionGrade(exception, exceptionGradeEnum);
		// 解析异常
		// 执行异常处理动作
		disposeFunction(null, finalExceptionGrade, analysisException(message, exception, finalExceptionGrade));
	}

	/**
	 * @description 处理异常
	 * @param message                  异常的信息
	 * @param exception                处理的异常
	 * @param exceptionDisposeFunction 异常的处理方法
	 *
	 * @date 2020年2月23日 上午10:48:17
	 * @version 1.2.0
	 */
	public void recordException(String message, Exception exception,
			ExceptionDisposeFunction exceptionDisposeFunction) {
		ExceptionGradeEnum finalExceptionGrade = finalExceptionGrade(exception, null);
		// 解析异常
		// 执行异常处理动作
		disposeFunction(exceptionDisposeFunction, finalExceptionGrade,
				analysisException(message, exception, finalExceptionGrade));
	}

	/**
	 * @description 处理异常
	 * @param message                  异常的信息
	 * @param exception                处理的异常
	 * @param exceptionGradeEnum       异常的等级
	 * @param exceptionDisposeFunction 异常处理的方法
	 *
	 * @date 2020年2月23日 上午10:48:37
	 * @version 1.2.0
	 */
	public void recordException(String message, Exception exception, ExceptionGradeEnum exceptionGradeEnum,
			ExceptionDisposeFunction exceptionDisposeFunction) {
		ExceptionGradeEnum finalExceptionGrade = finalExceptionGrade(exception, exceptionGradeEnum);
		// 解析异常
		// 执行异常处理动作
		disposeFunction(exceptionDisposeFunction, finalExceptionGrade,
				analysisException(message, exception, finalExceptionGrade));
	}

	/**
	 * @description 递归获得根本异常
	 * @param exception 需要获取根本异常的异常
	 * @return 根本异常
	 * @throws Exception 需要处理的异常包装内部信息丢失
	 *
	 * @date 2020年2月23日 下午9:16:27
	 * @version 1.2.0
	 */
	private Exception getPrimaryException(Exception exception) throws Exception {
		try {
			// 已经处理了异常为空的情况
			// 递归出口
			if (!ExceptionPack.class.isInstance(exception)) {
				return exception;
			}
			Exception exceptionPacked = Optional.ofNullable(((ExceptionPack) exception).getException())
					.orElseThrow(() -> new ExceptionPack("异常包装中丢失异常", ExceptionGradeEnum.WARN,
							new ForestException("异常包装内部信息丢失 ——> 无法处理") {

								/**
								 * @description 序列化编号
								 * 
								 * @author quark
								 * @date 2020年2月24日 下午1:21:37
								 */
								private static final long serialVersionUID = 1L;
							}));
			// 递归处理
			return getPrimaryException(exceptionPacked);
		} catch (Exception e) {
			throw new ExceptionPack("无法获得根本异常", e);
		}
	}

	/**
	 * @description 执行异常处理动作
	 * @param exceptionDisposeFunction 异常的处理的方法
	 * @param exceptionGradeEnum       异常的等级
	 * @param parseException           解析异常的拼接字符串
	 *
	 * @author quark
	 * @date 2020-8-8 12:05:35
	 * @version 2.0.1
	 */
	private void disposeFunction(ExceptionDisposeFunction exceptionDisposeFunction,
			ExceptionGradeEnum exceptionGradeEnum, StringBuilder parseException) {
		// 当异常包为空的时候
		if (null == parseException)
			throw new ForestRuntimeException(CustomString.ERROR_FINISH) {

				/**
				 * @description 序列化编号
				 * 
				 * @author quark
				 * @date 2020年5月13日 上午10:08:58
				 * @version 1.2.0
				 */
				private static final long serialVersionUID = 1L;
			};
		// 根据配置fatal异常执行退出程序
		switch (exceptionGradeEnum) {
		case ERROR:
			// 拼接异常解析的结尾并打印
			ExceptionStamper.INSTANCE.printException(addParseExceptionTail(parseException).toString(),
					exceptionGradeEnum);
			// 处理RuntimeException的异常信息
			String message = CustomString.ERROR_FINISH;
			if (exceptionDisposeFunction != null) {
				message += "，异常处理将不被执行";
			}
			// ERROR等级结束当前线程
			throw new ForestRuntimeException(message) {

				/**
				 * @description 序列化编号
				 * 
				 * @author quark
				 * @date 2020年5月13日 上午10:08:58
				 * @version 1.2.0
				 */
				private static final long serialVersionUID = 1L;
			};
		case FATAL:
			// 拼接异常解析的结尾并打印
			ExceptionStamper.INSTANCE.printException(addParseExceptionTail(parseException).toString(),
					exceptionGradeEnum);
			LOGGER.error(MARKER_FATAL, "系统崩溃退出");
			// 系统退出z
			System.exit(0);
			break;
		case WARN:
			// 拼接异常处理的信息
			parseException.append(CustomString.NEW_LINE).append(CustomString.BLANK).append(CustomString.BORDER_TAIL)
					.append(CustomString.NEW_LINE).append(CustomString.BORDER_LINE).append(CustomString.BORDER_TAIL)
					.append(CustomString.NEW_LINE).append(CustomString.BLANK).append(CustomString.BORDER_TAIL)
					.append(CustomString.NEW_LINE);
			if (exceptionDisposeFunction == null) {
				// 拼接无异常处理办法的信息
				parseException.append("\t没有设置异常处理动作");
				// 拼接异常解析的结尾并打印
				ExceptionStamper.INSTANCE.printException(addParseExceptionTail(parseException).toString(),
						exceptionGradeEnum);
				break;
			}
			// 执行动作
			try {
				// 拼接异常开始处理的信息
				parseException.append("        开始处理异常：【").append(exceptionDisposeFunction.hashCode()).append("】");
				// 拼接异常解析的结尾并打印
				ExceptionStamper.INSTANCE.printException(addParseExceptionTail(parseException).toString(),
						exceptionGradeEnum);
				exceptionDisposeFunction.action();
				LOGGER.info("异常处理：【{}】 执行完毕", +exceptionDisposeFunction.hashCode());
			} catch (Exception e) {
				LOGGER.warn("异常处理：【{}】 执行失败", exceptionDisposeFunction.hashCode(), e);
			}
			break;
		}
	}

	/**
	 * @description 拼接异常解析的结尾
	 * @return 拼接了结尾后的解析异常信息
	 *
	 * @author quark
	 * @version 2.0.1
	 */
	private StringBuilder addParseExceptionTail(StringBuilder parseException) {
		return parseException.append(CustomString.NEW_LINE).append(CustomString.BLANK).append(CustomString.BORDER_TAIL)
				.append(CustomString.NEW_LINE).append(CustomString.BORDER_LINE).append(CustomString.BORDER_TAIL)
				.append(CustomString.NEW_LINE);
	}

	/**
	 * @description 处理异常包【直接异常--间接异常--根本异常】
	 * @param message            异常的信息
	 * @param exception          处理的异常
	 * @param exceptionGradeEnum 异常的等级
	 * @return
	 *
	 * @date 2020年2月23日 下午9:17:12
	 * @version 1.2.0
	 */
	private StringBuilder analysisException(String message, Exception exception,
			ExceptionGradeEnum exceptionGradeEnum) {
		// 自处理空异常包direct
		if (analysisNullException(exception))
			return null;
		// 开始处理异常
		// 需要打印出来的异常日志
		StringBuilder exceptionLog = new StringBuilder(CustomString.NEW_LINE);
		String threadName = handleThreadNameLength(handleThreadNameLength(Thread.currentThread().getName()));
		exceptionLog.append("                                                                                        ")
				.append("Parse Exception:  ").append(exceptionGradeEnum.getLEVEL()).append(CustomString.NEW_LINE)
				.append(CustomString.BORDER_LINE).append(CustomString.BORDER_TAIL).append(CustomString.NEW_LINE)
				.append(CustomString.BLANK).append(CustomString.BORDER_TAIL).append(CustomString.NEW_LINE)
				.append(CustomString.DIVISION$2).append("direct   cause").append(CustomString.DIVISION$3);
		try {
			exceptionLog.append(CustomString.NEW_LINE).append(CustomString.LOG_HEAD$1)
					.append(String.format("%-6s", exceptionGradeEnum.getLEVEL())).append(CustomString.LOG_HEAD$2)
					.append(threadName).append(CustomString.LOG_HEAD$3)
					.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern(CustomString.TIME_FORMAT)))
					.append(CustomString.LOG_HEAD$4).append(analysisMessageLength(message))
					.append(CustomString.LOG_HEAD$5).append(CustomString.NEW_LINE)
					.append(getStackTraceBeginLine(new ForestException("无意义的") {

						/**
						 * @description 序列化编号
						 * 
						 * @author quark
						 * @date 2020年2月24日 下午1:13:57
						 */
						private static final long serialVersionUID = 1L;
					}, 3));
			// 获得根本异常
			Exception primaryException = getPrimaryException(exception);
			// 处理的是异常的情况【无间接异常】
			if (exception instanceof ExceptionPack) {
				ExceptionPack exceptionPack = (ExceptionPack) exception;
				// 拼接间接异常信息
				exceptionLog.append(recordIndirectException(exceptionPack));
			}
			// 拼接根本异常信息
			exceptionLog.append(CustomString.NEW_LINE).append(CustomString.BLANK).append(CustomString.BORDER_TAIL)
					.append(CustomString.NEW_LINE).append(CustomString.DIVISION$1).append(CustomString.NEW_LINE)
					.append(CustomString.DIVISION$2).append("primary  cause").append(CustomString.DIVISION$3)
					.append(CustomString.NEW_LINE);
			return addExceptionAnalysis(exceptionLog, primaryException);
		} catch (Exception e) {
			recordException("处理异常失败", e, ExceptionGradeEnum.ERROR);
			return null;
		}
	}

	/**
	 * @description 添加异常的解析
	 * @param exceptionLog 被添加的异常日志
	 * @param throwable    添加的异常
	 * @return 添加过后的异常日志
	 *
	 * @author quark
	 * @date 2020-8-6 23:09:44
	 * @version 2.0.1
	 */
	private StringBuilder addExceptionAnalysis(StringBuilder exceptionLog, Throwable throwable) {
		Class<? extends Throwable> classThrowable = throwable.getClass();
		String throwableClassName = classThrowable.getName();
		if (classThrowable.getSimpleName().equals(""))
			throwableClassName = throwableClassName + "【匿名类】：继承于 =>  " + classThrowable.getSuperclass().getName();
		exceptionLog.append(throwableClassName).append(": ").append(throwable.getMessage());
		StackTraceElement[] stackTrace = throwable.getStackTrace();
		for (StackTraceElement stackTraceElement : stackTrace) {
			exceptionLog.append(CustomString.NEW_LINE)
					.append(String.format("%-205s", CustomString.STACK_TRACE_HEAD$2 + stackTraceElement.toString()))
					.append(CustomString.BORDER_TAIL);
		}
		Throwable cause = throwable.getCause();
		if (cause != null)
			addExceptionAnalysis(exceptionLog.append(CustomString.NEW_LINE).append("Caused by: "), cause);
		return exceptionLog;
	}

	/**
	 * @description 获取line行后面的堆栈信息【自己new的异常】【共异常包处理器使用】
	 * @param throwable 需要处理的异常
	 * @param line      行数
	 * @return 异常的堆栈信息
	 * @throws Exception 获取异常堆栈信息失败
	 *
	 * @date 2020年2月26日 上午12:24:44
	 * @version 1.2.0
	 */
	private String getStackTraceBeginLine(Throwable throwable, int line) throws Exception {
		// 为了只打印程序员自己写的类，
		// 处理的ExceptionPack是程序员自己new的，通过堆栈信息获得异常的包名
		// 之后不属于本包的异常只打印一条供参考
		// 要想查看异常的完整堆栈信息，可以从根本异常的堆栈信息去查看
		String packageName = null;
		StringBuilder result = new StringBuilder();
		try {
			StackTraceElement[] stackTrace = Optional.ofNullable(throwable)
					.orElseThrow(() -> new ForestException("丢失待检测可抛物") {

						/**
						 * @description 序列化编号
						 * 
						 * @author quark
						 * @date 2020年2月26日 上午12:20:43
						 */
						private static final long serialVersionUID = 1L;
					}).getStackTrace();
			if (line > stackTrace.length || line < 0) {
				throw new ForestException("获取堆栈异常信息超出范围") {

					/**
					 * @description 序列化编号
					 * 
					 * @author quark
					 * @date 2020年2月26日 上午6:25:40
					 */
					private static final long serialVersionUID = 1L;
				};
			}
			for (int num = line - 1; num < stackTrace.length; num++) {
				StackTraceElement stackTraceElement = stackTrace[num];
				if (packageName == null) {
					String stackTraceElementOne = String.valueOf(stackTraceElement);
					// 获取项目的包名【需要程序员严格按照包名规范去建包】
					packageName = stackTraceElementOne.substring(0,
							getCharacterPosition(stackTraceElementOne, "\\.", 2));
				}
				result.append(String.format("%-205s", CustomString.STACK_TRACE_HEAD$2 + stackTraceElement));
				result.append(CustomString.BORDER_TAIL);
				// 不是本包的异常只打印一条供参考
				if (packageName != null && !String.valueOf(stackTraceElement).startsWith(packageName)) {
					break;
				}
				if (num != stackTrace.length - 1) {
					result.append(CustomString.NEW_LINE);
				}
			}
		} catch (Exception e) {
			throw new ExceptionPack("获取异常堆栈信息失败", ExceptionGradeEnum.WARN, e);
		}
		return result.toString();
	}

	/**
	 * @description 获取字符在字符串中第index次出现的位置
	 * @param string  需要解析的字符串
	 * @param appoint appoint符号
	 * @param index   第index出现
	 * @return 位置
	 *
	 * @date 2020年2月27日 上午1:08:32
	 * @version 1.2.0
	 */
	private int getCharacterPosition(String string, String appoint, int index) {
		// 这里是获取appoint符号的位置
		Matcher matcher = Pattern.compile(appoint).matcher(string);
		int num = 0;
		while (matcher.find()) {
			num++;
			// 当appoint符号第index次出现的位置
			if (num == index) {
				return matcher.start();
			}
		}
		return -1;
	}

	/**
	 * @description 处理信息的长度
	 * @return 处理后的信息
	 *
	 * @author quark
	 * @date 2020-8-4 22:27:16
	 * @version 2.0.1
	 */
	private String analysisMessageLength(String message) {
		if (null == message || message.trim().isEmpty())
			return "丢失异常信息";
		message = message.trim();
		if (message.length() <= 28) {
			return message;
		}
		return message.substring(0, 27) + "……";
	}

	/**
	 * @description 解析空异常
	 * @param exception 需要解析的异常
	 * @return 是否是空异常
	 *
	 * @author quark
	 * @date 2020-7-23 16:42:40
	 * @version 2.0.1
	 */
	private boolean analysisNullException(Exception exception) {
		if (null != exception)
			return false;
		if (ExceptionStamper.EXCEPTION_LOGGER.isErrorEnabled()) {
			try {
				ExceptionStamper.INSTANCE.printException(ExceptionGradeEnum.ERROR,
						createStandardLog(LocalDateTime.now(), ExceptionGradeEnum.ERROR,
								Thread.currentThread().getName(), "禁止处理空异常包装",
								getStackTraceFormatting(new ForestException("无意义的") {

									/**
									 * @description 序列化编号
									 * 
									 * @author quark
									 * @date 2020-7-23 14:33:09
									 * @version 1.2.2
									 */
									private static final long serialVersionUID = 1L;
								}, 3, true).append(CustomString.NEW_LINE).toString(), true));
			} catch (Exception e) {
				ExceptionStamper.INSTANCE.printException("forest内部异常解析error", e, ExceptionGradeEnum.FATAL);
			}
		}
		return true;
	}

	/**
	 * @description 打印标准日志
	 * @param localDateTime      日志时间
	 * @param exceptionGradeEnum 日志等级
	 * @param threadName         日志线程
	 * @param message            日志信息
	 * @param stackInfo          日志堆栈信息
	 * @param common             根据是否是普通的异常打印选择堆栈信息头
	 * @return 生成的标准日志
	 *
	 * @author quark
	 * @date 2020-8-8 12:34:14
	 * @version 2.0.1
	 */
	private String createStandardLog(LocalDateTime localDateTime, ExceptionGradeEnum exceptionGradeEnum,
			String threadName, String message, String stackInfo, boolean common) {
		return new StringBuilder(CustomString.LOG_HEAD$1).append(String.format("%-6s", exceptionGradeEnum.getLEVEL()))
				.append(CustomString.LOG_HEAD$2).append(handleThreadNameLength(threadName))
				.append(CustomString.LOG_HEAD$3)
				.append(localDateTime.format(DateTimeFormatter.ofPattern(CustomString.TIME_FORMAT)))
				.append(CustomString.LOG_HEAD$4).append(message).append(CustomString.LOG_HEAD$5)
				.append(CustomString.NEW_LINE)
				.append(common ? CustomString.STACK_TRACE_HEAD$1 : CustomString.STACK_TRACE_HEAD$2).append(stackInfo)
				.toString();
	}

	/**
	 * @description 处理线程名称
	 * @param threadName 待处理的线程名称
	 * @return 处理完的线程名称
	 *
	 * @author quark
	 * @date 2020-8-4 13:19:21
	 * @version 2.0.1
	 */
	private String handleThreadNameLength(String threadName) {
		// 这里不做去空格的校验【内部调用方法】
		if (null == threadName || threadName.isEmpty()) {
			return "****  ";
		}
		if (threadName.length() < 9) {
			return String.format("%-9s", threadName);
		}
		if (threadName.length() > 11) {
			return threadName.substring(0, 11);
		}
		return threadName;
	}

	/**
	 * @description 获得最终的异常等级
	 * @param exception          需要处理的异常
	 * @param exceptionGradeEnum 处理设置的异常等级
	 * @return 处理后的异常等级
	 *
	 * @author forest
	 * @date 2020-7-27 1:01:16
	 * @version 2.0.1
	 */
	private ExceptionGradeEnum finalExceptionGrade(Exception exception, ExceptionGradeEnum exceptionGradeEnum) {
		exceptionGradeEnum = Optional.ofNullable(exceptionGradeEnum).orElse(defaultExceptionGrade);
		// 处理直接异常的异常等级【exceptionPack的内部异常登记已经在其内部解决】
		if (exception instanceof ExceptionPack) {
			ExceptionGradeEnum exceptionGrade = ((ExceptionPack) exception).getExceptionGradeEnum();
			exceptionGradeEnum = exceptionGrade.getGRADE() > exceptionGradeEnum.getGRADE() ? exceptionGrade
					: exceptionGradeEnum;
		} else if (exception instanceof RuntimeException) {
			exceptionGradeEnum = ExceptionGradeEnum.ERROR;
		}
		return exceptionGradeEnum;
	}

	/**
	 * 
	 * @description 处理间接异常【内部方法，处理前获取根本异常已经排除了间接异常为空的情况】
	 * @param exceptionPack 被处理的间接异常
	 * @throws Exception 异常包装内部信息丢失,获得堆栈信息失败
	 * @date 2019年10月19日 上午10:37:43
	 * @version 1.2.0
	 */
	private String recordIndirectException(ExceptionPack exceptionPack) throws Exception {
		StringBuilder result = new StringBuilder(CustomString.NEW_LINE);
		result.append(CustomString.BLANK).append(CustomString.BORDER_TAIL).append(CustomString.NEW_LINE)
				.append(CustomString.DIVISION$1).append(CustomString.NEW_LINE).append(CustomString.DIVISION$2)
				.append("indirect cause").append(CustomString.DIVISION$3).append(CustomString.NEW_LINE)
				.append(createStandardLog(exceptionPack.getGeneratedTime(), exceptionPack.getExceptionGradeEnum(),
						handleThreadNameLength(exceptionPack.getThreadName()), exceptionPack.getMessage(),
						Optional.ofNullable(getStackTraceFormatting(exceptionPack, 0, false))
								.filter(p1 -> !p1.toString().trim().equals(""))
								.orElse(getStackTraceFormatting(exceptionPack, 1, false)).toString(),
						false));
		// 拼接间接异常的产生的位置【存在没有调用出处的异常处理，则打印的位置就是异常生成处】
		// 递归处理
		if (exceptionPack.getException() instanceof ExceptionPack) {
			result.append(recordIndirectException((ExceptionPack) exceptionPack.getException()));
		}
		return result.toString();
	}

	/**
	 * @description 获得异常堆的指定行的堆栈信息
	 * @param throwable 需要处理的异常
	 * @param line      行数
	 * @return 指定行的堆栈信息
	 * @throws Exception 获取异常堆栈信息失败
	 *
	 * @date 2020年2月25日 下午11:50:29
	 * @version 1.2.0
	 */
	private StringBuilder getStackTraceFormatting(Throwable throwable, int line, boolean common) throws Exception {
		if (null == throwable) {
			LOGGER.warn("可抛物为空,无法获得指定行的堆栈信息");
			return null;
		}
		StringBuilder result = new StringBuilder();
		try {
			StackTraceElement[] stackTraceElements = Optional.ofNullable(throwable)
					.orElseThrow(() -> new ForestException("丢失待检测可抛物") {

						/**
						 * @description 序列化编号
						 * 
						 * @author quark
						 * @date 2020年2月26日 上午12:20:43
						 */
						private static final long serialVersionUID = 1L;
					}).getStackTrace();
			if (line > stackTraceElements.length || line < -1) {
				throw new ForestException("获取堆栈异常信息超出范围") {

					/**
					 * @description 序列化编号
					 * 
					 * @author quark说
					 * @date 2020年2月26日 上午12:21:43
					 */
					private static final long serialVersionUID = 1L;
				};
			}
			int index = 0;
			for (StackTraceElement stackTraceElement : stackTraceElements) {
				if (line != -1 && index++ != line)
					continue;
				if (common) {
					result.append(stackTraceElement);
				} else {
					result.append(String.format("%-194s", stackTraceElement)).append(CustomString.BORDER_TAIL);
				}
				if ((index - 1) == line)
					break;
			}
		} catch (Exception e) {
			throw new ExceptionPack("获取异常堆栈信息失败", ExceptionGradeEnum.WARN, e);
		}
		return result;
	}


	@Override
	protected Void analysisPack(ProcessPack t) {
		// TODO Auto-generated method stub
		return null;
	}

}
